/*
 * @Author: 唉诺
 * @Date: 2021-02-27 09:43:44
 */
import Phaser from 'phaser-ce'
export default class extends Phaser.State {
  create () {
    this.bg = this.add.tileSprite(0, 112, this.game.width, this.game.height, 'background')
    this.ground = this.add.tileSprite(0, this.game.height - 112, this.game.width, 112, 'ground')
    this.pipeGroup = this.add.group()
    this.pipeGroup.enableBody = true
    this.bird = this.add.sprite(50, 150, 'bird')
    this.bird.animations.add('fly')
    this.bird.animations.play('fly', 12, true)
    this.bird.anchor.setTo(0.5, 0.5)
    this.scoreText = this.add.bitmapText(this.game.world.centerX - 20, 30, 'flappy_font', '0', 36)
    this.readyText = this.add.image(this.game.width / 2, 40, 'ready_text')
    this.playTip = this.add.image(this.game.width / 2, 400, 'play_tip')
    this.readyText.anchor.setTo(0.5, 0)
    this.playTip.anchor.setTo(0.5, 0)
    this.physics.enable(this.bird, Phaser.Physics.ARCADE)
    this.bird.body.gravity.y = 0
    this.bird.body.bounce.y = 0.5
    this.physics.enable(this.ground, Phaser.Physics.ARCADE)
    this.ground.body.immovable = true

    this.ground.bringToTop()

    this.hasStarted = false

    this.time.events.loop(1000, () => {
      this.generatePipes()
    })
    this.time.events.stop(false)

    this.input.onDown.addOnce(() => {
      this.startGame()
    })
    /* 音乐 */
    this.soundFly = this.add.sound('fly_sound')
    this.soundScore = this.add.sound('score_sound')
    this.soundHitPipe = this.add.sound('hit_pipe_sound')
    this.soundHitGround = this.add.sound('hit_ground_sound')

    // bg.autoScroll(-20, 0)
    // ground.autoScroll(-100, 0)
  }
  update () {
    console.log(this.pipeGroup.length)
    if (!this.hasStarted) return
    this.physics.arcade.collide(this.bird, this.ground, this.hitGround, null, this)
    this.physics.arcade.overlap(this.bird, this.pipeGroup, this.hitPipe, null, this)
    if (!this.bird.inWorld) this.hitCeil()
    if (this.bird.angle < 90) this.bird.angle += 2.5
    this.pipeGroup.forEachExists(this.checkScore, this)
  };
  startGame () {
    this.gameSpeed = 200
    this.gameIsOver = false
    this.hasHitGround = false
    this.hasHitCeil = false
    this.hasStarted = true
    this.score = 0
    this.bg.autoScroll(-(this.gameSpeed / 10), 0)
    this.ground.autoScroll(-this.gameSpeed, 0)
    this.bird.body.gravity.y = 1150
    this.readyText.destroy()
    this.playTip.destroy()
    this.time.events.start()
    this.input.onDown.add(this.fly, this)
  }
  fly () {
    this.bird.body.velocity.y = -350
    // this.bird.body.velocity.x = 10
    this.add.tween(this.bird).to({angle: -30}, 100, null, true, 0, 0, false)
    this.soundFly.play()
  }
  generatePipes () {
    const gap = 180
    const difficulty = 150 // difficulty越大越简单
    const position = 80 + Math.floor((this.game.height - 112 - difficulty - gap) * Math.random())
    const topPipeY = position - 320
    const bottomPipeY = position + gap
    if (this.resetPipe(topPipeY, bottomPipeY)) return
    this.add.sprite(this.game.width, topPipeY, 'pipe', 0, this.pipeGroup)
    this.add.sprite(this.game.width, bottomPipeY, 'pipe', 1, this.pipeGroup)
    this.pipeGroup.setAll('checkWorldBounds', true)
    this.pipeGroup.setAll('outOfBoundsKill', true)
    this.pipeGroup.setAll('body.velocity.x', -this.gameSpeed)
    // this.pipeGroup.setAll('body.immovable', true)
  }
  resetPipe (topPipeY, bottomPipeY) {
    var i = 0
    this.pipeGroup.forEachDead(function (pipe) {
      if (pipe.y <= 0) {
        pipe.reset(this.game.width, topPipeY)
        pipe.hasScored = false
      } else {
        pipe.reset(this.game.width, bottomPipeY)
      }
      pipe.body.velocity.x = -this.gameSpeed
      i++
    }, this)
    return i === 2
  };
  hitCeil () {
    if (this.hasHitCeil) return
    this.hasHitCeil = true
    this.soundHitPipe.play()
    this.gameOver(true)
  }
  hitPipe () {
    if (this.gameIsOver) return
    this.soundHitPipe.play()
    this.gameOver()
  }
  hitGround () {
    if (this.hasHitGround) return
    this.hasHitGround = true
    this.soundHitGround.play()
    this.gameOver(true)
  };
  checkScore (pipe) {
    if (!pipe.hasScored && pipe.y <= 0 && pipe.x <= this.bird.x - 17 - 54) {
      pipe.hasScored = true
      this.scoreText.text = ++this.score
      this.soundScore.play()
      return true
    }
    return false
  }
  // eslint-disable-next-line camelcase
  gameOver (show_text) {
    this.gameIsOver = true
    this.stopGame()
    // eslint-disable-next-line camelcase
    if (show_text) this.showGameOverText()
  }
  showGameOverText () {
    this.scoreText.destroy()
    this.bestScore = this.bestScore || 0
    if (this.score > this.bestScore) this.bestScore = this.score
    this.gameOverGroup = this.add.group()
    const gameOverText = this.gameOverGroup.create(this.game.width / 2, 0, 'game_over')
    const scoreboard = this.gameOverGroup.create(this.game.width / 2, 70, 'score_board')
    this.add.bitmapText(this.game.width / 2 + 60, 105, 'flappy_font', this.score + '', 20, this.gameOverGroup)
    this.add.bitmapText(this.game.width / 2 + 60, 153, 'flappy_font', this.bestScore + '', 20, this.gameOverGroup)
    const replayBtn = this.add.button(this.game.width / 2, 210, 'btn', () => {
      this.state.start('Play')
    }, this, null, null, null, null, this.gameOverGroup)
    gameOverText.anchor.setTo(0.5, 0)
    scoreboard.anchor.setTo(0.5, 0)
    replayBtn.anchor.setTo(0.5, 0)
    this.gameOverGroup.y = 100
  }
  stopGame () {
    this.bg.stopScroll()
    this.ground.stopScroll()
    this.pipeGroup.forEachExists(function (pipe) {
      pipe.body.velocity.x = 0
    }, this)
    this.bird.animations.stop('fly', 0)
    this.input.onDown.remove(this.fly, this)
    this.time.events.stop(true)
  };
}
